// Energia.cpp: implementation of the CEnergia class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Energia.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CEnergia::CEnergia( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice )
{
	if( FAILED( m_pDevice->CreateVertexBuffer( (802 + 40*21 + 20*40)*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbSphere ) ) )
		throw CSystemException( "unable to create sphere vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( (3*21*40 + 3*40*20)*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibSphere ) ) )
		throw CSystemException( "unable to create sphere index buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 6*1000*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbBars ) ) )
		throw CSystemException( "unable to create bars vertex buffer" );

	PSIMPLEVERTEX			pVertices;
	DWORD					dwIndex = 0;
	LPWORD					pIndices;

	m_pvbSphere->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	m_vSphere[dwIndex++] = Polar2Cartesian3d( 1.0f, 0.0f, 0.0f );
	m_vSphere[dwIndex++] = Polar2Cartesian3d( 1.0f, 0.0f, H_PI );

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f, 0.0f, 0.0f ), 0x80545a7b );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f, 0.0f, H_PI ), 0x80545a7b );

	for( DWORD i = 0 ; i < 40 ; i++ )
		for( DWORD j = 0 ; j < 20 ; j++, dwIndex++ )
		{
			m_vSphere[dwIndex] = Polar2Cartesian3d( 1.0f, (FLOAT)i*H_2PI/40.0f, (FLOAT)(j+1)*H_PI/21.0f );
			*(pVertices++) = SIMPLEVERTEX( m_vSphere[dwIndex], 0x80545a7b );
		}

	for( i = 0 ; i < 40 ; i++ )
		for( DWORD j = 0 ; j < 21 ; j++, dwIndex++ )
		{		
			m_vSphere[dwIndex] = Polar2Cartesian3d( 1.0f, (FLOAT)i*H_2PI/40.0f + 0.03f, (FLOAT)(j+1)*H_PI/21.0f - 0.05f );
			*(pVertices++) = SIMPLEVERTEX( m_vSphere[dwIndex], 0x20515a7b );
		}

	for( i = 0 ; i < 40 ; i++ )
		for( DWORD j = 0 ; j < 20 ; j++, dwIndex++ )
		{		
			m_vSphere[dwIndex] = Polar2Cartesian3d( 1.0f, (FLOAT)i*H_2PI/40.0f + 0.07f, (FLOAT)(j+1)*H_PI/21.0f + 0.03f );
			*(pVertices++) = SIMPLEVERTEX( m_vSphere[dwIndex], 0x20545a7b );
		}

	m_pvbSphere->Unlock();
	
	m_pibSphere->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );

	for( i = 0 ; i < 40 ; i++ )
	{
		*(pIndices++) = 0;
		*(pIndices++) = (WORD)( i*20 + 2 );
		*(pIndices++) = (WORD)( i*21 + 802 );

		for( DWORD j = 0 ; j < 19 ; j++ )
		{
			*(pIndices++) = (WORD)( i*20 + j + 2 );
			*(pIndices++) = (WORD)( i*20 + j + 1 + 2 );
			*(pIndices++) = (WORD)( i*21 + j + 1 + 802 );
		}
		
		*(pIndices++) = (WORD)( i*20 + 19 + 2 );
		*(pIndices++) = 1;
		*(pIndices++) = (WORD)( i*21 + 20 + 802 );
	}

	//1024

	for( i = 0 ; i < 20 ; i++ )
	{
		for( DWORD j = 0 ; j < 39 ; j++ )
		{
			*(pIndices++) = (WORD)( j*20 + i + 2 );
			*(pIndices++) = (WORD)( ( j+1 )*20 + i + 2 );
			*(pIndices++) = (WORD)( j*20 + i + 1642 );
		}

		*(pIndices++) = (WORD)( 39*20 + i + 2 );
		*(pIndices++) = (WORD)( 0*20 + i + 2 );
		*(pIndices++) = (WORD)( 39*20 + i + 1642 );
	}

	m_pibSphere->Unlock();

	for( i = 0 ; i < 3 ; i++ )
		m_vEmiter[i] = Polar2Cartesian3d( 0.8f, H_2PI*RAND(), H_2PI*RAND() );

	m_pvbBars->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 100 ; i++ )
	{	
		FLOAT				fRadiusShift = 0.25f*SIGNEDRAND();

		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f - 0.2f ), -10.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f - 0.2f ), 0x25000000 );
		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f + 0.2f ), -10.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f + 0.2f ), 0x25000000 );
		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f - 0.1f ),  20.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f - 0.1f ), 0x25000000 );

		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f + 0.2f ), -10.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f + 0.2f ), 0x25000000 );
		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f - 0.1f ),  20.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f - 0.1f ), 0x25000000 );
		*(pVertices++) = SIMPLEVERTEX( ( 1.0f + fRadiusShift )*cosf( (FLOAT)i*H_2PI*0.01f + 0.1f ),  20.0f,  ( 1.0f + fRadiusShift )*sinf( (FLOAT)i*H_2PI*0.01f + 0.1f ), 0x25000000 );
		
	}

	m_pvbBars->Unlock();
}

CEnergia::~CEnergia()
{
	
}

BOOL CEnergia::UpdateFrame( FLOAT fTime )
{
	// std setup

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.75f, 1.0f, 1000.0f ) );
	m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( he3d_CVector( 0, 0, -10 ), he3d_CVector( 0, 0, 0 ), 0 ) );

	m_fTime = fTime;

	he3d_CMatrix			mtx = ScaleMtx( 0.8f + 0.2f*sinf( 0.1f*fTime ) )*RotationMtx( 0.3f*fTime, -0.25f*fTime, 0.4f*fTime );
	he3d_CVector			vEmiters[3];

	vEmiters[0] = m_vEmiter[0]*ScaleMtx( 1.35f + 0.25f*sinf( 0.3f*fTime + 0.50f ) )*RotationMtx( -0.40f*fTime, -0.30f*fTime,  0.50f*fTime );
	vEmiters[1] = m_vEmiter[1]*ScaleMtx( 1.35f + 0.25f*sinf( 0.3f*fTime + 0.25f ) )*RotationMtx(  0.20f*fTime, -0.40f*fTime, -0.30f*fTime );
	vEmiters[2] = m_vEmiter[2]*ScaleMtx( 1.35f + 0.25f*sinf( 0.3f*fTime + 0.75f ) )*RotationMtx( -0.25f*fTime,  0.20f*fTime,  0.40f*fTime );

	he3d_CVector			v, p, pos;
	PSIMPLEVERTEX			pVertices;

	m_pvbSphere->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( DWORD i = 0 ; i < 2442 ; i++ )
	{	
		pos = m_vSphere[i]*mtx;
		p = pos;

		for( DWORD j = 0 ; j < 3 ; j++ )
		{		
			v = p - vEmiters[j];			
			pos = pos + Normalize( v )*0.4f/Length( v );
		}

		pVertices[i].m_vPos = pos;
	}

	m_pvbSphere->Unlock();

	return TRUE;
}

BOOL CEnergia::RenderEfx()
{
	m_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0xffffff, 0.0f, 0 );

	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetRenderState( D3DRS_ZENABLE, FALSE );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetTexture( 0, NULL );

	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );

	m_pDevice->SetTransform( D3DTS_WORLD, YRotationMtx( 0.5f*m_fTime ) );

	m_pDevice->SetStreamSource( 0, m_pvbBars, sizeof(SIMPLEVERTEX) );
	m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 200 );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	//m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	//m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

	m_pDevice->SetTransform( D3DTS_WORLD, TranslationMtx( 2.0f, 1.0f, 0.0f ) );

	m_pDevice->SetStreamSource( 0, m_pvbSphere, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibSphere, 0 );

	m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 802 + 21*40 + 20*40, 0, 21*40 + 20*40 );	
		

	return TRUE;
}
